#include "dtu_data_collect.h"
#include "dtu_log.h"
#include "dtu_memory.h"
#include <math.h>
#include <sys/select.h>
#include <unistd.h>
#include <termios.h>

/* 全局数据采集管理器 */
static collect_manager_t g_collect_manager = {0};

/* 内部函数声明 */
static void* collect_thread_func(void* arg);
static dtu_error_t collect_device_data(device_config_t* device, collect_result_t* result);
static dtu_error_t collect_point_data(const data_point_t* point, data_value_t* value);
static dtu_error_t convert_raw_data(const uint16_t* raw_data, const data_point_t* point, data_value_t* value);
static device_config_t* find_device(const char* device_name);
static void free_devices(void);
static dtu_error_t collect_device_with_poll_string(device_config_t* device, collect_result_t* result);
static int hex_string_to_bytes(const char* hex_str, uint8_t* bytes, size_t max_bytes);
static void bytes_to_hex_string(const uint8_t* bytes, size_t byte_count, char* hex_str, size_t max_hex_len);
static uint16_t calculate_modbus_crc16(const uint8_t* data, size_t length);
static int add_modbus_crc(uint8_t* data, size_t data_len, size_t max_buffer_size);

dtu_error_t dtu_data_collect_init(const collect_config_t* config,
                                  const serial_config_t* rs485_config,
                                  const serial_config_t* rs232_config)
{
    if (g_collect_manager.initialized) {
        return DTU_OK;
    }

    if (!config || !rs485_config || !rs232_config) {
        return DTU_ERROR_INVALID_PARAM;
    }

    memset(&g_collect_manager, 0, sizeof(collect_manager_t));

    /* 复制配置 */
    g_collect_manager.config = *config;

    /* 初始化RS485 Modbus上下文 */
    g_collect_manager.modbus_ctx_rs485 = dtu_modbus_init(MODBUS_MODE_RTU, rs485_config);
    if (!g_collect_manager.modbus_ctx_rs485) {
        DTU_LOG_ERROR("Failed to initialize RS485 Modbus context");
        return DTU_ERROR;
    }

    /* 初始化RS232 Modbus上下文 */
    g_collect_manager.modbus_ctx_rs232 = dtu_modbus_init(MODBUS_MODE_RTU, rs232_config);
    if (!g_collect_manager.modbus_ctx_rs232) {
        DTU_LOG_ERROR("Failed to initialize RS232 Modbus context");
        dtu_modbus_cleanup(g_collect_manager.modbus_ctx_rs485);
        return DTU_ERROR;
    }

    /* 初始化互斥锁 */
    if (pthread_mutex_init(&g_collect_manager.mutex, NULL) != 0) {
        dtu_modbus_cleanup(g_collect_manager.modbus_ctx_rs485);
        dtu_modbus_cleanup(g_collect_manager.modbus_ctx_rs232);
        return DTU_ERROR;
    }

    /* 初始化统计信息 */
    g_collect_manager.stats.start_time = time(NULL);

    g_collect_manager.initialized = true;

    DTU_LOG_INFO("Data collection manager initialized");
    return DTU_OK;
}

void dtu_data_collect_cleanup(void)
{
    if (!g_collect_manager.initialized) {
        return;
    }

    /* 停止采集 */
    dtu_data_collect_stop();

    pthread_mutex_lock(&g_collect_manager.mutex);

    /* 释放设备配置 */
    free_devices();

    /* 清理Modbus上下文 */
    if (g_collect_manager.modbus_ctx_rs485) {
        dtu_modbus_cleanup(g_collect_manager.modbus_ctx_rs485);
        g_collect_manager.modbus_ctx_rs485 = NULL;
    }
    if (g_collect_manager.modbus_ctx_rs232) {
        dtu_modbus_cleanup(g_collect_manager.modbus_ctx_rs232);
        g_collect_manager.modbus_ctx_rs232 = NULL;
    }

    g_collect_manager.initialized = false;

    pthread_mutex_unlock(&g_collect_manager.mutex);
    pthread_mutex_destroy(&g_collect_manager.mutex);

    DTU_LOG_INFO("Data collection manager cleanup completed");
}

dtu_error_t dtu_data_collect_start(void)
{
    DTU_LOG_INFO("dtu_data_collect_start() called");

    if (!g_collect_manager.initialized) {
        DTU_LOG_ERROR("Data collection manager not initialized");
        return DTU_ERROR;
    }

    pthread_mutex_lock(&g_collect_manager.mutex);

    if (g_collect_manager.running) {
        DTU_LOG_INFO("Data collection already running");
        pthread_mutex_unlock(&g_collect_manager.mutex);
        return DTU_OK;
    }

    /* 连接RS485 Modbus */
    if (dtu_modbus_connect(g_collect_manager.modbus_ctx_rs485) != DTU_OK) {
        DTU_LOG_WARN("Failed to connect RS485 Modbus (continuing anyway)");
    }

    /* 连接RS232 Modbus */
    if (dtu_modbus_connect(g_collect_manager.modbus_ctx_rs232) != DTU_OK) {
        DTU_LOG_WARN("Failed to connect RS232 Modbus (continuing anyway)");
    }

    g_collect_manager.running = true;

    /* 创建采集线程 */
    if (pthread_create(&g_collect_manager.collect_thread, NULL, collect_thread_func, NULL) != 0) {
        g_collect_manager.running = false;
        dtu_modbus_disconnect(g_collect_manager.modbus_ctx_rs485);
        dtu_modbus_disconnect(g_collect_manager.modbus_ctx_rs232);
        pthread_mutex_unlock(&g_collect_manager.mutex);
        DTU_LOG_ERROR("Failed to create collect thread");
        return DTU_ERROR;
    }

    pthread_mutex_unlock(&g_collect_manager.mutex);

    DTU_LOG_INFO("Data collection started");
    return DTU_OK;
}

dtu_error_t dtu_data_collect_stop(void)
{
    DTU_LOG_INFO("dtu_data_collect_stop() called");

    if (!g_collect_manager.initialized) {
        DTU_LOG_INFO("Data collection manager not initialized");
        return DTU_OK;
    }

    if (!g_collect_manager.running) {
        DTU_LOG_INFO("Data collection not running");
        return DTU_OK;
    }

    pthread_mutex_lock(&g_collect_manager.mutex);
    g_collect_manager.running = false;
    pthread_mutex_unlock(&g_collect_manager.mutex);

    /* 等待采集线程结束 */
    pthread_join(g_collect_manager.collect_thread, NULL);

    /* 断开Modbus连接 */
    dtu_modbus_disconnect(g_collect_manager.modbus_ctx_rs485);
    dtu_modbus_disconnect(g_collect_manager.modbus_ctx_rs232);

    DTU_LOG_INFO("Data collection stopped");
    return DTU_OK;
}

dtu_error_t dtu_data_collect_add_device(const device_config_t* device)
{
    if (!g_collect_manager.initialized || !device) {
        return DTU_ERROR_INVALID_PARAM;
    }

    pthread_mutex_lock(&g_collect_manager.mutex);

    /* 检查设备是否已存在 */
    if (find_device(device->name)) {
        pthread_mutex_unlock(&g_collect_manager.mutex);
        return DTU_ERROR_BUSY;
    }

    /* 扩展设备数组 */
    device_config_t* new_devices = DTU_REALLOC(g_collect_manager.devices,
                                               (g_collect_manager.device_count + 1) * sizeof(device_config_t));
    if (!new_devices) {
        pthread_mutex_unlock(&g_collect_manager.mutex);
        return DTU_ERROR_MEMORY;
    }

    g_collect_manager.devices = new_devices;

    /* 复制设备配置 */
    device_config_t* new_device = &g_collect_manager.devices[g_collect_manager.device_count];
    *new_device = *device;

    /* 复制数据点数组 */
    if (device->point_count > 0 && device->points) {
        new_device->points = DTU_MALLOC(device->point_count * sizeof(data_point_t));
        if (!new_device->points) {
            pthread_mutex_unlock(&g_collect_manager.mutex);
            return DTU_ERROR_MEMORY;
        }
        memcpy(new_device->points, device->points, device->point_count * sizeof(data_point_t));
    } else {
        new_device->points = NULL;
        new_device->point_count = 0;
    }

    g_collect_manager.device_count++;

    pthread_mutex_unlock(&g_collect_manager.mutex);

    DTU_LOG_INFO("Device added: %s (slave_id=%d, points=%d)", 
                 device->name, device->slave_id, device->point_count);
    return DTU_OK;
}

dtu_error_t dtu_data_collect_trigger(const char* device_name)
{
    if (!g_collect_manager.initialized) {
        return DTU_ERROR;
    }

    pthread_mutex_lock(&g_collect_manager.mutex);

    if (device_name) {
        /* 采集指定设备 */
        device_config_t* device = find_device(device_name);
        if (!device) {
            pthread_mutex_unlock(&g_collect_manager.mutex);
            return DTU_ERROR_NOT_FOUND;
        }

        if (!device->enabled) {
            pthread_mutex_unlock(&g_collect_manager.mutex);
            return DTU_ERROR_NOT_SUPPORTED;
        }

        collect_result_t result;
        dtu_error_t ret = collect_device_data(device, &result);
        
        if (ret == DTU_OK && g_collect_manager.data_callback) {
            g_collect_manager.data_callback(&result, g_collect_manager.callback_user_data);
        }

        dtu_data_collect_free_result(&result);
        pthread_mutex_unlock(&g_collect_manager.mutex);
        return ret;
    } else {
        /* 采集所有设备 */
        for (int i = 0; i < g_collect_manager.device_count; i++) {
            device_config_t* device = &g_collect_manager.devices[i];
            if (!device->enabled) {
                continue;
            }

            collect_result_t result;
            if (collect_device_data(device, &result) == DTU_OK) {
                if (g_collect_manager.data_callback) {
                    g_collect_manager.data_callback(&result, g_collect_manager.callback_user_data);
                }
            }
            dtu_data_collect_free_result(&result);
        }
        pthread_mutex_unlock(&g_collect_manager.mutex);
        return DTU_OK;
    }
}

dtu_error_t dtu_data_collect_set_callback(void (*callback)(const collect_result_t* result, void* user_data), 
                                          void* user_data)
{
    if (!g_collect_manager.initialized) {
        return DTU_ERROR;
    }

    pthread_mutex_lock(&g_collect_manager.mutex);
    g_collect_manager.data_callback = callback;
    g_collect_manager.callback_user_data = user_data;
    pthread_mutex_unlock(&g_collect_manager.mutex);

    return DTU_OK;
}

dtu_error_t dtu_data_collect_get_stats(collect_stats_t* stats)
{
    if (!g_collect_manager.initialized || !stats) {
        return DTU_ERROR_INVALID_PARAM;
    }

    pthread_mutex_lock(&g_collect_manager.mutex);
    *stats = g_collect_manager.stats;
    pthread_mutex_unlock(&g_collect_manager.mutex);

    return DTU_OK;
}

dtu_error_t dtu_data_collect_reload_devices(void)
{
    if (!g_collect_manager.initialized) {
        return DTU_ERROR_NOT_SUPPORTED;
    }

    pthread_mutex_lock(&g_collect_manager.mutex);

    /* 清理现有设备配置 */
    if (g_collect_manager.devices) {
        for (int i = 0; i < g_collect_manager.device_count; i++) {
            if (g_collect_manager.devices[i].points) {
                DTU_FREE(g_collect_manager.devices[i].points);
            }
        }
        DTU_FREE(g_collect_manager.devices);
        g_collect_manager.devices = NULL;
        g_collect_manager.device_count = 0;
    }

    pthread_mutex_unlock(&g_collect_manager.mutex);

    DTU_LOG_INFO("Device configuration reloaded, devices cleared. Ready for new configuration.");
    return DTU_OK;
}

void dtu_data_collect_free_result(collect_result_t* result)
{
    if (result && result->values) {
        DTU_FREE(result->values);
        result->values = NULL;
        result->value_count = 0;
    }
}

const char* dtu_data_type_string(data_type_t type)
{
    switch (type) {
        case DATA_TYPE_INT16: return "int16";
        case DATA_TYPE_UINT16: return "uint16";
        case DATA_TYPE_INT32: return "int32";
        case DATA_TYPE_UINT32: return "uint32";
        case DATA_TYPE_FLOAT: return "float";
        case DATA_TYPE_DOUBLE: return "double";
        case DATA_TYPE_BOOL: return "bool";
        default: return "unknown";
    }
}

data_type_t dtu_data_type_from_string(const char* str)
{
    if (!str) return DATA_TYPE_UINT16;
    
    if (strcmp(str, "int16") == 0) return DATA_TYPE_INT16;
    if (strcmp(str, "uint16") == 0) return DATA_TYPE_UINT16;
    if (strcmp(str, "int32") == 0) return DATA_TYPE_INT32;
    if (strcmp(str, "uint32") == 0) return DATA_TYPE_UINT32;
    if (strcmp(str, "float") == 0) return DATA_TYPE_FLOAT;
    if (strcmp(str, "double") == 0) return DATA_TYPE_DOUBLE;
    if (strcmp(str, "bool") == 0) return DATA_TYPE_BOOL;
    
    return DATA_TYPE_UINT16;
}

/* 内部函数实现 */
static void* collect_thread_func(void* arg)
{
    (void)arg;

    DTU_LOG_INFO("Data collection thread started");

    while (g_collect_manager.running) {
        if (g_collect_manager.config.auto_collect) {
            /* 自动采集所有启用的设备 */
            DTU_LOG_INFO("=== Data Collection Cycle: %d devices ===", g_collect_manager.device_count);
            pthread_mutex_lock(&g_collect_manager.mutex);

            for (int i = 0; i < g_collect_manager.device_count; i++) {
                device_config_t* device = &g_collect_manager.devices[i];
                if (!device->enabled) {
                    continue;
                }

                collect_result_t result;
                if (collect_device_data(device, &result) == DTU_OK) {
                    g_collect_manager.stats.successful_collections++;

                    if (g_collect_manager.data_callback) {
                        g_collect_manager.data_callback(&result, g_collect_manager.callback_user_data);
                    }
                } else {
                    g_collect_manager.stats.failed_collections++;
                }

                g_collect_manager.stats.total_collections++;
                g_collect_manager.stats.last_collect_time = time(NULL);

                dtu_data_collect_free_result(&result);
            }

            pthread_mutex_unlock(&g_collect_manager.mutex);
            DTU_LOG_INFO("=== Cycle completed, next in %ds ===", g_collect_manager.config.interval);
        } else {
            DTU_LOG_DEBUG("Auto collection is disabled");
        }

        /* 等待采集间隔 */
        sleep(g_collect_manager.config.interval);
    }

    DTU_LOG_INFO("Data collection thread stopped");
    return NULL;
}

static dtu_error_t collect_device_data(device_config_t* device, collect_result_t* result)
{
    if (!device || !result) {
        return DTU_ERROR_INVALID_PARAM;
    }

    memset(result, 0, sizeof(collect_result_t));
    DTU_STRNCPY(result->device_name, device->name, sizeof(result->device_name));
    result->slave_id = device->slave_id;
    result->collect_time = time(NULL);

    /* 如果设备有轮询字符串但没有数据点，使用轮询字符串进行采集 */
    if (device->point_count == 0 && strlen(device->poll_string) > 0) {
        return collect_device_with_poll_string(device, result);
    }

    if (device->point_count == 0) {
        return DTU_OK;
    }

    /* 分配数据值数组 */
    result->values = DTU_MALLOC(device->point_count * sizeof(data_value_t));
    if (!result->values) {
        return DTU_ERROR_MEMORY;
    }

    result->value_count = device->point_count;

    /* 采集每个数据点 */
    for (int i = 0; i < device->point_count; i++) {
        data_point_t* point = &device->points[i];
        data_value_t* value = &result->values[i];

        if (!point->enabled) {
            /* 跳过禁用的数据点 */
            memset(value, 0, sizeof(data_value_t));
            DTU_STRNCPY(value->name, point->name, sizeof(value->name));
            value->valid = false;
            continue;
        }

        dtu_error_t ret = collect_point_data(point, value);
        if (ret == DTU_OK) {
            result->success_count++;
            g_collect_manager.stats.successful_points++;
        } else {
            result->error_count++;
            g_collect_manager.stats.failed_points++;
        }
        g_collect_manager.stats.total_points++;
    }

    DTU_LOG_DEBUG("Device %s: collected %d/%d points",
                  device->name, result->success_count, result->value_count);
    return DTU_OK;
}

static dtu_error_t collect_point_data(const data_point_t* point, data_value_t* value)
{
    if (!point || !value) {
        return DTU_ERROR_INVALID_PARAM;
    }

    memset(value, 0, sizeof(data_value_t));
    DTU_STRNCPY(value->name, point->name, sizeof(value->name));
    DTU_STRNCPY(value->unit, point->unit, sizeof(value->unit));
    value->type = point->data_type;
    value->timestamp = time(NULL);

    /* 读取原始数据 */
    uint16_t raw_data[4] = {0}; /* 最多支持64位数据 */
    dtu_error_t ret = DTU_ERROR;

    /* 根据设备的串口ID选择正确的Modbus上下文 */
    modbus_context_t* modbus_ctx = NULL;

    /* 需要从设备配置中获取串口ID，这里暂时使用RS485作为默认 */
    /* TODO: 需要在数据点结构中添加串口ID或从设备配置中获取 */
    modbus_ctx = g_collect_manager.modbus_ctx_rs485;

    switch (point->function_code) {
        case MODBUS_FC_READ_HOLDING_REGISTERS:
            ret = dtu_modbus_read_holding_registers(modbus_ctx,
                                                   point->slave_id, point->address, point->count, raw_data);
            break;
        case MODBUS_FC_READ_INPUT_REGISTERS:
            ret = dtu_modbus_read_input_registers(modbus_ctx,
                                                 point->slave_id, point->address, point->count, raw_data);
            break;
        default:
            DTU_LOG_ERROR("Unsupported function code: %d", point->function_code);
            value->error_code = DTU_ERROR_NOT_SUPPORTED;
            return DTU_ERROR_NOT_SUPPORTED;
    }

    if (ret != DTU_OK) {
        DTU_LOG_ERROR("Failed to read data point %s: %s", point->name, dtu_error_string(ret));
        value->error_code = ret;
        return ret;
    }

    /* 转换原始数据 */
    ret = convert_raw_data(raw_data, point, value);
    if (ret == DTU_OK) {
        value->valid = true;
    } else {
        value->error_code = ret;
    }

    return ret;
}

static dtu_error_t convert_raw_data(const uint16_t* raw_data, const data_point_t* point, data_value_t* value)
{
    if (!raw_data || !point || !value) {
        return DTU_ERROR_INVALID_PARAM;
    }

    union {
        uint16_t u16[4];
        uint32_t u32[2];
        int16_t i16[4];
        int32_t i32[2];
        float f32[2];
        double f64;
    } data;

    /* 复制原始数据并处理字节序 */
    for (int i = 0; i < point->count && i < 4; i++) {
        if (point->byte_order == BYTE_ORDER_LITTLE_ENDIAN) {
            /* 小端序：交换字节 */
            data.u16[i] = ((raw_data[i] & 0xFF) << 8) | ((raw_data[i] >> 8) & 0xFF);
        } else {
            /* 大端序：直接复制 */
            data.u16[i] = raw_data[i];
        }
    }

    /* 根据数据类型转换 */
    switch (point->data_type) {
        case DATA_TYPE_INT16:
            value->value.i16_value = data.i16[0];
            /* 应用缩放和偏移 */
            if (point->scale != 0.0f) {
                value->value.i16_value = (int16_t)(value->value.i16_value * point->scale + point->offset);
            }
            break;

        case DATA_TYPE_UINT16:
            value->value.u16_value = data.u16[0];
            if (point->scale != 0.0f) {
                value->value.u16_value = (uint16_t)(value->value.u16_value * point->scale + point->offset);
            }
            break;

        case DATA_TYPE_INT32:
            if (point->count >= 2) {
                value->value.i32_value = data.i32[0];
                if (point->scale != 0.0f) {
                    value->value.i32_value = (int32_t)(value->value.i32_value * point->scale + point->offset);
                }
            } else {
                return DTU_ERROR_INVALID_PARAM;
            }
            break;

        case DATA_TYPE_UINT32:
            if (point->count >= 2) {
                value->value.u32_value = data.u32[0];
                if (point->scale != 0.0f) {
                    value->value.u32_value = (uint32_t)(value->value.u32_value * point->scale + point->offset);
                }
            } else {
                return DTU_ERROR_INVALID_PARAM;
            }
            break;

        case DATA_TYPE_FLOAT:
            if (point->count >= 2) {
                value->value.float_value = data.f32[0];
                if (point->scale != 0.0f) {
                    value->value.float_value = value->value.float_value * point->scale + point->offset;
                }
            } else {
                return DTU_ERROR_INVALID_PARAM;
            }
            break;

        case DATA_TYPE_DOUBLE:
            if (point->count >= 4) {
                value->value.double_value = data.f64;
                if (point->scale != 0.0f) {
                    value->value.double_value = value->value.double_value * point->scale + point->offset;
                }
            } else {
                return DTU_ERROR_INVALID_PARAM;
            }
            break;

        case DATA_TYPE_BOOL:
            value->value.bool_value = (data.u16[0] != 0);
            break;

        default:
            return DTU_ERROR_INVALID_PARAM;
    }

    return DTU_OK;
}

static device_config_t* find_device(const char* device_name)
{
    if (!device_name) {
        return NULL;
    }

    for (int i = 0; i < g_collect_manager.device_count; i++) {
        if (strcmp(g_collect_manager.devices[i].name, device_name) == 0) {
            return &g_collect_manager.devices[i];
        }
    }

    return NULL;
}

static void free_devices(void)
{
    for (int i = 0; i < g_collect_manager.device_count; i++) {
        if (g_collect_manager.devices[i].points) {
            DTU_FREE(g_collect_manager.devices[i].points);
        }
    }

    if (g_collect_manager.devices) {
        DTU_FREE(g_collect_manager.devices);
        g_collect_manager.devices = NULL;
    }

    g_collect_manager.device_count = 0;
}

/* 16进制字符串转字节数组 - 按照AT指令文档，输入是ASCII字符的16进制表示 */
static int hex_string_to_bytes(const char* hex_str, uint8_t* bytes, size_t max_bytes)
{
    if (!hex_str || !bytes) {
        return -1;
    }

    size_t hex_len = strlen(hex_str);
    if (hex_len % 2 != 0) {
        return -1; /* 16进制字符串长度必须是偶数 */
    }

    size_t byte_count = hex_len / 2;
    if (byte_count > max_bytes) {
        return -1; /* 超出缓冲区大小 */
    }

    /* 将16进制字符串转换为字节数组 */
    for (size_t i = 0; i < byte_count; i++) {
        char hex_byte[3] = {hex_str[i * 2], hex_str[i * 2 + 1], '\0'};
        char* endptr;
        long val = strtol(hex_byte, &endptr, 16);

        if (*endptr != '\0' || val < 0 || val > 255) {
            return -1; /* 无效的16进制字符 */
        }

        bytes[i] = (uint8_t)val;
    }

    return (int)byte_count;
}

/* 字节数组转16进制字符串 */
static void bytes_to_hex_string(const uint8_t* bytes, size_t byte_count, char* hex_str, size_t max_hex_len)
{
    if (!bytes || !hex_str || max_hex_len < (byte_count * 2 + 1)) {
        if (hex_str && max_hex_len > 0) {
            hex_str[0] = '\0';
        }
        return;
    }

    for (size_t i = 0; i < byte_count; i++) {
        snprintf(hex_str + i * 2, 3, "%02X", bytes[i]);
    }
}

/* 使用轮询字符串进行设备数据采集 */
static dtu_error_t collect_device_with_poll_string(device_config_t* device, collect_result_t* result)
{
    if (!device || !result) {
        return DTU_ERROR_INVALID_PARAM;
    }

    /* 将16进制字符串转换为字节数组 */
    uint8_t poll_bytes[256];
    int poll_len = hex_string_to_bytes(device->poll_string, poll_bytes, sizeof(poll_bytes));
    if (poll_len < 0) {
        DTU_LOG_ERROR("Device %s: Failed to parse poll string: %s", device->name, device->poll_string);
        return DTU_ERROR_INVALID_PARAM;
    }

    /* 如果启用CRC校验，添加Modbus CRC16校验 */
    if (device->crc_enable) {
        poll_len = add_modbus_crc(poll_bytes, poll_len, sizeof(poll_bytes));
        if (poll_len < 0) {
            DTU_LOG_ERROR("Device %s: Failed to add CRC to poll string", device->name);
            return DTU_ERROR_INVALID_PARAM;
        }
    }

    /* 准备发送数据的16进制字符串 */
    char send_hex[512];
    bytes_to_hex_string(poll_bytes, poll_len, send_hex, sizeof(send_hex));

    /* 实际的串口发送和接收逻辑 */
    uint8_t response_data[256];
    int response_len = 0;

    /* 根据串口ID选择正确的Modbus上下文 */
    modbus_context_t* modbus_ctx = NULL;
    const char* serial_name = NULL;

    if (device->serial_id == 1) {
        modbus_ctx = g_collect_manager.modbus_ctx_rs485;
        serial_name = "RS485";
    } else if (device->serial_id == 2) {
        modbus_ctx = g_collect_manager.modbus_ctx_rs232;
        serial_name = "RS232";
    } else {
        DTU_LOG_ERROR("Device %s: Invalid serial_id %d", device->name, device->serial_id);
        result->raw_hex_data[0] = '\0';
        result->raw_data_length = 0;
        result->has_raw_data = false;
        result->values = NULL;
        result->value_count = 0;
        result->success_count = 0;
        result->error_count = 1;
        return DTU_ERROR_INVALID_PARAM;
    }

    /* 执行串口通信 */
    bool communication_success = false;
    char error_msg[128] = {0};

    if (modbus_ctx && modbus_ctx->serial_fd >= 0) {
        /* 发送轮询数据 */
        ssize_t bytes_sent = write(modbus_ctx->serial_fd, poll_bytes, poll_len);
        if (bytes_sent != poll_len) {
            snprintf(error_msg, sizeof(error_msg), "Send failed (%zd/%d bytes)", bytes_sent, poll_len);
        } else {
            /* 刷新输出缓冲区 */
            tcdrain(modbus_ctx->serial_fd);

            /* 等待响应数据 */
            usleep(50000); /* 等待50ms让设备处理请求 */

            /* 接收响应数据 */
            fd_set read_fds;
            struct timeval timeout;
            FD_ZERO(&read_fds);
            FD_SET(modbus_ctx->serial_fd, &read_fds);
            timeout.tv_sec = device->timeout / 1000;
            timeout.tv_usec = (device->timeout % 1000) * 1000;

            int select_result = select(modbus_ctx->serial_fd + 1, &read_fds, NULL, NULL, &timeout);
            if (select_result > 0 && FD_ISSET(modbus_ctx->serial_fd, &read_fds)) {
                /* 有数据可读 */
                ssize_t bytes_received = read(modbus_ctx->serial_fd, response_data, sizeof(response_data));
                if (bytes_received > 0) {
                    response_len = (int)bytes_received;
                    communication_success = true;
                } else {
                    snprintf(error_msg, sizeof(error_msg), "Read failed");
                }
            } else if (select_result == 0) {
                snprintf(error_msg, sizeof(error_msg), "Timeout (%dms)", device->timeout);
            } else {
                snprintf(error_msg, sizeof(error_msg), "Select error");
            }
        }
    } else {
        /* 如果串口未连接，使用模拟数据（用于测试） */
        const char* mock_response = "010300020001";
        response_len = hex_string_to_bytes(mock_response, response_data, sizeof(response_data));
        communication_success = true;
        snprintf(error_msg, sizeof(error_msg), "Mock data (no %s)", serial_name);
    }

    /* 处理采集结果并输出完整的日志 */
    if (response_len > 0) {
        char response_hex[512];
        bytes_to_hex_string(response_data, response_len, response_hex, sizeof(response_hex));

        /* 存储原始16进制数据用于直接转发 */
        DTU_STRNCPY(result->raw_hex_data, response_hex, sizeof(result->raw_hex_data));
        result->raw_data_length = response_len;
        result->has_raw_data = true;
        result->values = NULL;
        result->value_count = 0;
        result->success_count = 1;
        result->error_count = 0;

        /* 输出完整的采集日志 */
        DTU_LOG_INFO("Device %s [%s]: Send=%s → Recv=%s (%d bytes) ✓",
                     device->name, serial_name, send_hex, response_hex, response_len);
    } else {
        result->raw_hex_data[0] = '\0';
        result->raw_data_length = 0;
        result->has_raw_data = false;
        result->values = NULL;
        result->value_count = 0;
        result->success_count = 0;
        result->error_count = 1;

        /* 输出失败的采集日志 */
        DTU_LOG_ERROR("Device %s [%s]: Send=%s → %s ✗",
                      device->name, serial_name, send_hex, error_msg);
    }

    return DTU_OK;
}

/* Modbus CRC16校验计算 */
static uint16_t calculate_modbus_crc16(const uint8_t* data, size_t length)
{
    uint16_t crc = 0xFFFF;

    for (size_t i = 0; i < length; i++) {
        crc ^= data[i];

        for (int j = 0; j < 8; j++) {
            if (crc & 0x0001) {
                crc = (crc >> 1) ^ 0xA001;
            } else {
                crc >>= 1;
            }
        }
    }

    return crc;
}

/* 添加Modbus CRC16校验到数据末尾 */
static int add_modbus_crc(uint8_t* data, size_t data_len, size_t max_buffer_size)
{
    if (!data || data_len + 2 > max_buffer_size) {
        return -1;
    }

    uint16_t crc = calculate_modbus_crc16(data, data_len);

    /* Modbus CRC16是小端序 */
    data[data_len] = crc & 0xFF;        /* CRC低字节 */
    data[data_len + 1] = (crc >> 8) & 0xFF;  /* CRC高字节 */

    return (int)(data_len + 2);
}

/* 手动执行一次数据采集（用于云端轮询） */
dtu_error_t dtu_data_collect_execute_once(int device_id)
{
    if (!g_collect_manager.initialized) {
        DTU_LOG_ERROR("Data collection manager not initialized");
        return DTU_ERROR;
    }

    DTU_LOG_INFO("Executing manual data collection for device %d", device_id);

    /* 简化实现：直接触发一次采集循环 */
    /* 这里可以根据实际需求实现具体的单设备采集逻辑 */

    DTU_LOG_INFO("Manual data collection triggered for device %d", device_id);

    /* 如果采集线程正在运行，这次手动采集会在下一个采集周期执行 */
    /* 如果采集线程未运行，可以在这里实现单次采集逻辑 */

    return DTU_OK;
}
